using System.Collections;
using System.Collections.Generic;
using System.IO;


namespace EpisodeWizard.Core
{

	public class Guess<T>
	{
		/// <summary>
		/// All the choices: text and weight
		/// The AutoSelect method computes the probability of each choice to select the best one
		/// </summary>
		public Dictionary<T, float>	Choices
		{
			get;
			set;
		}
		
		/// <summary>
		/// The best choice, or selected one
		/// It is not necessarily included in the choice list
		/// </summary>
		public T SelectedValue
		{
			get;
			set;
		}
		
		public Guess()
		{
			Choices = new Dictionary<T,float>();
			SelectedValue = default(T);
		}

		/// <summary>
		/// Add a choice
		/// </summary>
		public void AddChoice(T value, float Weight)
		{
			if (Choices.ContainsKey(value))
			{
				Choices[value] += Weight;
			}
			else
			{
				Choices.Add(value, Weight);
			}
		}

		/// <summary>
		/// Clear all choices
		/// </summary>
		public void ClearChoices()
		{
			Choices.Clear();
		}

		/// <summary>
		/// Tries to  select the best  choice, and use it as the SelectedValue
		/// If no choice is clearly better than the others, sets SelectedValue to null
		/// </summary>
		public void AutoSelect()
		{
			// Select most probable choice, with probability P
			// It will be selected if no other choice is more probable than P/2
			// For example, we will be able to pick a choice if
			// 2 choices: 	67; 32
			// 3 choices:	66; 32; 1
			// 3 choices: 	55; 23; 22
			// 4 choices: 	45; 19; 18; 18
			
			if (Choices.Count == 0)
			{
				SelectedValue = default(T);
			}
			else if (Choices.Count == 1)
			{
				List<KeyValuePair<T, float>> ChoicesAsList = new List<KeyValuePair<T, float>>(Choices);
				SelectedValue = ChoicesAsList[0].Key;
			}
			else
			{
				List<KeyValuePair<T, float>> ChoicesAsList = new List<KeyValuePair<T, float>>(Choices);
				ChoicesAsList.Sort(new ChoiceComparer());

				KeyValuePair<T, float> Best = ChoicesAsList[ChoicesAsList.Count-1];
				KeyValuePair<T, float> SecondBest = ChoicesAsList[ChoicesAsList.Count - 2];
				if (SecondBest.Value <= Best.Value / 2.0)
				{
					SelectedValue = Best.Key;
				}
				else
				{
					SelectedValue = default(T);
				}
			}
		}

		private class ChoiceComparer : System.Collections.Generic.IComparer<KeyValuePair<T, float>>
		{
			public int Compare(KeyValuePair<T, float> A, KeyValuePair<T, float> B)
			{
				if (A.Value == B.Value)
				{
					return 0;
				}
				else
				{
					return (A.Value > B.Value) ? 1 : -1;
				}
			}
		}
	}

}

